/*
 * Author  : Leo <lipf160627@163.com>
 * Created : 2025-7-27
 * Desc    : Tasks of FreeRTOS
 */

#include "tasks.hpp"

#include "asrpro.hpp"
#include "config.hpp"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led.hpp"
#include <memory>

Tasks::Tasks(std::shared_ptr<Components> components)
    : m_components(components)
{
}

void Tasks::start()
{
    xTaskCreate(&Tasks::asrpro_task, "asrpro_task", 2048, this, tskIDLE_PRIORITY + 1, nullptr);
    xTaskCreate(&Tasks::lcd_task, "lcd_task", 2048, this, tskIDLE_PRIORITY + 1, nullptr);
    xTaskCreate(&Tasks::ultrasonic_task, "ultrasonic_task", 2048, this, tskIDLE_PRIORITY + 1, nullptr);
}

void Tasks::asrpro_task(void* pvParameters)
{
    Tasks* instance = static_cast<Tasks*>(pvParameters);
    if (instance) {
        std::shared_ptr<Asrpro> asrpro = instance->m_components->asrpro;
        std::shared_ptr<CoMcu>  coMcu  = instance->m_components->coMcu;
        std::shared_ptr<Led>    led    = instance->m_components->led;
        while (1)
        {
            printf("Ready to recv asrpro cmd\n");
            uint8_t cmd = asrpro->recvCmd();
            printf("ASRPRO CMD: %d\n", cmd);
            switch (cmd)
            {
                case ASRPRO_CMD_FORWARD:
                    coMcu->forward(10, 0);
                    break;
                case ASRPRO_CMD_BACK:
                    coMcu->back(10, 0);
                    break;
                case ASRPRO_CMD_TURN_LEFT:
                    coMcu->turnLeft(90, 45);
                    break;
                case ASRPRO_CMD_TURN_RIGHT:
                    coMcu->turnRight(90, 45);
                    break;
                case ASRPRO_CMD_STOP:
                    coMcu->stop();
                    break;
                case ASRPRO_CMD_CLOCKWISE:
                    coMcu->turnRight(0, 45);
                    break;
                case ASRPRO_CMD_ANTICLOCKWISE:
                    coMcu->turnLeft(0, 45);
                    break;
                case ASRPRO_CMD_OPEN_FRONT_LIGHT:
                    led->on(LED_FRONT_LEFT_PIN);
                    led->on(LED_FRONT_RIGHT_PIN);
                    asrpro->sendAck(true);
                    break;
                case ASRPRO_CMD_CLOSE_FRONT_LIGHT:
                    led->off(LED_FRONT_LEFT_PIN);
                    led->off(LED_FRONT_RIGHT_PIN);
                    asrpro->sendAck(true);
                    break;
                case ASRPRO_CMD_OPEN_BACK_LIGHT:
                    led->on(LED_BACK_LEFT_PIN);
                    led->on(LED_BACK_RIGHT_PIN);
                    asrpro->sendAck(true);
                    break;
                case ASRPRO_CMD_CLOSE_BACK_LIGHT:
                    led->off(LED_BACK_LEFT_PIN);
                    led->off(LED_BACK_RIGHT_PIN);
                    asrpro->sendAck(true);
                    break;
                case ASRPRO_CMD_HELLO:
                    break;
                default:
                    ESP_LOGE("Tasks", "Unsupported command %d", cmd);
                    break;
            }
        }
    }
}

void Tasks::lcd_task(void* pvParameters)
{
    Tasks* instance = static_cast<Tasks*>(pvParameters);
    if (instance) {
        while (1)
        {
            vTaskDelay(pdMS_TO_TICKS(100));
        }
    }
}

void Tasks::ultrasonic_task(void* pvParameters)
{
    Tasks* instance = static_cast<Tasks*>(pvParameters);
    if (instance) {
        while (1)
        {
            vTaskDelay(pdMS_TO_TICKS(100));
        }
    }
}
